﻿using System;
using System.Reflection;
using CSRedis;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NetMicro.Cache.DelayBus;
using NetMicro.Cache.InMemoryProvider;
using NetMicro.Cache.RedisProvider;
using NetMicro.Core.Ioc.Attributes;

namespace NetMicro.Cache
{
    /// <summary>
    /// 缓存相关扩展
    /// </summary>
    public static class ServiceCollectionExtensions
    {


        /// <summary>
        /// Redis和内存缓存
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        public static IServiceCollection AddCacheWithRedis(this IServiceCollection services, IConfiguration configuration, string singleKey = "CsRedisConfig:SingleConnectString")
        {
            //内存缓存
            services.AddCache();
            string singleConfig = configuration.GetSection(singleKey).Value;
            services.AddRedis(singleConfig);
            return services;
        }


        /// <summary>
        /// Redis缓存
        /// </summary>
        /// <param name="services"></param>
        /// <param name="connect"></param>
        /// <returns></returns>
        public static IServiceCollection AddRedis(this IServiceCollection services, string connect)
        {
            Console.WriteLine($"RedisClient获取连接{connect}");
            CSRedisClient redisSingle = new CSRedisClient(connect);
            Console.WriteLine("RedisClient实例化成功");
            RedisHelper.Initialization(redisSingle);
            services.AddSingleton<IRedisCache, CsRedisCache>();
            services.AddSingleton<ICacheSerializer, JsonCacheSerializer>();
            services.AddSingleton<IDistributedCache>(new Microsoft.Extensions.Caching.Redis.CSRedisCache(redisSingle));
            return services;
        }


        /// <summary>
        /// 内存缓存
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddCache(this IServiceCollection services)
        {
            services.AddMemoryCache();
            services.AddSingleton<IInMemoryCache, MemoryCache>();
            return services;
        }

        /// <summary>
        /// 添加redis延迟任务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddRedisDelay(this IServiceCollection services)
        {
            services.AddSingleton<IDelayedMessageProcessor, DelayedMessageProcessor>();
            services.AddSingleton<IDelayTaskService, DelayTaskService>();
            services.AddHostedService<RedisDelayHostService>();
            return services;
        }

        /// <summary>
        /// 添加redis延迟任务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddRedisDelayHandle<DelayProcessor>(this IServiceCollection services)
            where DelayProcessor : class, IDelayProcessor
        {
            string topic = !typeof(DelayProcessor).IsDefined(typeof(InjectionAttribute)) ? typeof(DelayProcessor).Name : typeof(DelayProcessor).GetCustomAttribute<InjectionAttribute>().Named;
            DelayTopic.Add(topic);
            return services;
        }
    }
}
